package com.cn.intercepter;

import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.remoting.RemoteConnectFailureException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.cn.utils.FormSubmitResult;
import com.cn.utils.RRException;
import com.cn.utils.exception.ErrorConstant;

import javax.servlet.ServletException;

import java.io.IOException;
import java.net.ConnectException;

/**
 * @Description: 全局异常
 * Author lv bin
 * @date 2017/3/17 9:35
 * version V1.0.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {


    //运行时异常
	@ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public FormSubmitResult runtimeExceptionHandler(RuntimeException runtimeException) {
        logException(runtimeException);
        return FormSubmitResult.FAILED(ErrorConstant.RUNTIME_EXCEPTION.getCode(), ErrorConstant.RUNTIME_EXCEPTION.getMsg());
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public FormSubmitResult nullPointerExceptionHandler(NullPointerException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.NULL_POINTER_EXCEPTION.getCode(), ErrorConstant.NULL_POINTER_EXCEPTION.getMsg());
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    @ResponseBody
    public FormSubmitResult classCastExceptionHandler(ClassCastException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.CLASS_CAST_EXCEPTION.getCode(), ErrorConstant.CLASS_CAST_EXCEPTION.getMsg());
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    @ResponseBody
    public FormSubmitResult iOExceptionHandler(IOException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.IO_EXCEPTION.getCode(), ErrorConstant.IO_EXCEPTION.getMsg());
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    @ResponseBody
    public FormSubmitResult noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.NO_SUCH_METHOD_EXCEPTION.getCode(), ErrorConstant.NO_SUCH_METHOD_EXCEPTION.getMsg());
    }

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    @ResponseBody
    public FormSubmitResult indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.INDEX_OUT_OF_BOUNDS_EXCEPTION.getCode(), ErrorConstant.INDEX_OUT_OF_BOUNDS_EXCEPTION.getMsg());
    }

    //网络异常
    @ExceptionHandler(ConnectException.class)
    @ResponseBody
    public FormSubmitResult connectException(ConnectException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.CONNECT_EXCEPTION.getCode(), ErrorConstant.CONNECT_EXCEPTION.getMsg());
    }

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    public FormSubmitResult requestNotReadable(HttpMessageNotReadableException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.BAD_REQUEST.getCode(), ErrorConstant.BAD_REQUEST.getMsg());
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseBody
    public FormSubmitResult requestTypeMismatch(TypeMismatchException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.BAD_REQUEST.getCode(), ErrorConstant.BAD_REQUEST.getMsg());

    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseBody
    public FormSubmitResult requestMissingServletRequest(MissingServletRequestParameterException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.BAD_REQUEST.getCode(), ErrorConstant.BAD_REQUEST.getMsg());
    }

    @ExceptionHandler({ ServletException.class })
    @ResponseBody
    public FormSubmitResult http404(ServletException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.NOT_FOUND_REQUEST.getCode(), ErrorConstant.NOT_FOUND_REQUEST.getMsg());
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseBody
    public FormSubmitResult request405(HttpRequestMethodNotSupportedException ex) {
        logException(ex);
        return FormSubmitResult.FAILED(ErrorConstant.METHOD_NOT_ALLOWED.getCode(), ErrorConstant.METHOD_NOT_ALLOWED.getMsg());
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    @ResponseBody
    public FormSubmitResult request406(HttpMediaTypeNotAcceptableException ex) {
        logException(ex);

        return FormSubmitResult.FAILED(ErrorConstant.NOT_ACCEPTABLE.getCode(), ErrorConstant.NOT_ACCEPTABLE.getMsg());
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    @ResponseBody
    public FormSubmitResult server500(RuntimeException runtimeException) {
        logException(runtimeException);
        return FormSubmitResult.FAILED(ErrorConstant.INTERNAL_SERVER_ERROR.getCode(), ErrorConstant.INTERNAL_SERVER_ERROR.getMsg());
    }
    
    //hessian 客户端连接失败
    @ExceptionHandler({RemoteConnectFailureException.class})
    @ResponseBody
    public FormSubmitResult connectException(RuntimeException runtimeException) {
    	logException(runtimeException);
    	return FormSubmitResult.FAILED(ErrorConstant.HESSIAN_CONNECT_EXCEPTION.getCode(), ErrorConstant.HESSIAN_CONNECT_EXCEPTION.getMsg());
    }

    //自定义 异常
    @ExceptionHandler({RRException.class})
    @ResponseBody
    public FormSubmitResult appWebException(RRException reException) {
        logException(reException);
        
        return FormSubmitResult.FAILED(reException.getCode(), reException.getMsg());

    }
    

    /**
     * 异常记录
     * @param e
     */
    private void logException(Exception e){
        e.printStackTrace();
    }
}
